import time, json
from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
from django.http import HttpResponse, QueryDict, Http404, JsonResponse
from django.shortcuts import render
from django.views import View
from public import update_data, create_data, delete_data, verify_obj, PaginatorPage, access_auto_page, delete_access, categoryList
from system.forms import *
from system.models import *
from public.redis_pool import conn
from tl_book.settings import NORMAL_AUTH_TIME, FREEZE_TIME


class SystemPage(View):  # 站点设置

    @method_decorator(login_required)
    def get(self, request):
        system = SystemModel.objects.first()
        if system is None:
            system = SystemModel()  # todo 建议统一处理初始化系统
            system.save()
        return render(request, 'set_system.html', context={'data': dict(system)})

    @method_decorator(login_required)
    def post(self, request):
        return update_data(request, SystemForm, SystemModel, request.POST.get('uuid'))

    def http_method_not_allowed(self, request, *args, **kwargs):
        return HttpResponse(f'限制的{request.method}请求，请使用其他请求！')


class NavigationList(View):  # 分类列表

    @method_decorator(login_required)
    def get(self, request):
        return render(request, 'navigationList.html', context={'NavList': NavigationModel.objects.order_by('-create_time').filter(is_delete=False).all()})

    @method_decorator(login_required)
    def delete(self, request):
        uuid = QueryDict(request.body).get('uuid')
        return delete_data(uuid, NavigationModel)


class Navigation(View):  # 添加分类

    @method_decorator(login_required)
    def get(self, request):
        data = categoryList(NavigationModel.objects.filter(is_delete=False).values_list('uuid', 'column_name', 'column_parent'))
        return JsonResponse({'code': 0, 'category': data})

    @method_decorator(login_required)
    def post(self, request):
        return create_data(request, NavigationForm, NavigationModel)


class NavigationEdit(View):  # 修改分类

    @method_decorator(login_required)
    def get(self, request):
        uuid = request.GET.get('uuid', 'None')
        obj = NavigationModel.objects.filter(uuid=uuid).first()
        if not verify_obj(obj): return JsonResponse({'code': 4, 'msg': '参数错误', 'error': '未成功获取数据'})
        return JsonResponse({"code": 0, 'data': dict(obj)})

    @method_decorator(login_required)
    def post(self, request):
        uuid = request.POST.get('uuid', 'None')
        if uuid == request.POST.get('column_parent'): return JsonResponse({'code': 1, 'msg': '更新数据失败', 'error': '上级分类不可选择自己'})
        return update_data(request, NavigationEditForm, NavigationModel, uuid)


class NovelList(View):  # 小说列表

    @method_decorator(login_required)
    def get(self, request):
        search = request.GET.get('search')
        if search:
            data_list, page = PaginatorPage(request, NovelModel.objects.filter(novel_name=search).all())
        else:
            data_list, page = PaginatorPage(request, NovelModel.objects.order_by('-create_time').all())
        return render(request, 'novelList.html', context={'novelList': data_list, 'page': page})

    @method_decorator(login_required)
    def delete(self, request):
        uuid = QueryDict(request.body).get('uuid')
        try:
            obj = NovelModel.objects.filter(uuid=uuid).first()
            if not verify_obj(obj): return JsonResponse({'code': 1, 'msg': '删除数据失败', 'error': '参数有误，未检测到数据'})
            ChapterModel.objects.filter(novel=obj).delete()
            obj.delete()
        except Exception as e:
            return JsonResponse({'code': 4, 'msg': '删除数据异常', 'error': str(e)})
        return JsonResponse({'code': 0, 'msg': '删除数据成功'})

    @method_decorator(login_required)
    def post(self, request):
        uuidList = request.POST.get('uuidList').split('|*TL*|')
        if not uuidList: return JsonResponse({'code': 1, 'msg': '删除数据失败', 'error': '参数有误，未检测到参数'})
        for uuid in uuidList:
            try:
                obj = NovelModel.objects.filter(uuid=uuid)
                if not obj.first(): continue
                ChapterModel.objects.filter(novel=obj).delete()
                obj.delete()
            except Exception as e:
                return JsonResponse({'code': 4, 'msg': '删除数据异常', 'error': str(e)})
        return JsonResponse({'code': 0, 'msg': f'删除{len(uuidList)}条数据成功'})


class CommentView(View):  # 评论列表

    @method_decorator(login_required)
    def get(self, request):
        search = request.GET.get('search')
        if search:
            novel = NovelModel.objects.filter(novel_name=search).first()
            data_list, page = PaginatorPage(request, Comment_Model.objects.filter(content_uuid=novel).all())
        else:
            data_list, page = PaginatorPage(request, Comment_Model.objects.order_by('-create_time').all())
        return render(request, 'commentList.html', context={'dataList': data_list, 'page': page})

    @method_decorator(login_required)
    def delete(self, request):
        uuid = QueryDict(request.body).get('uuid')
        return delete_data(uuid, Comment_Model)


class LinkView(View):  # 链接列表

    @method_decorator(login_required)
    def get(self, request):
        data_list, page = PaginatorPage(request,
                                        Blogroll_Model.objects.order_by('-create_time').all().values('uuid', 'update_time', 'link_name', 'link_url', 'link_end_date',
                                                                                                     'link_remark'))
        return render(request, 'linkList.html', context={'dataList': data_list, 'page': page})

    @method_decorator(login_required)
    def delete(self, request):
        uuid = QueryDict(request.body).get('uuid')
        return delete_data(uuid, Blogroll_Model)

    @method_decorator(login_required)
    def post(self, request):
        return create_data(request, LinkForm, Blogroll_Model)


class AdView(View):

    @method_decorator(login_required)
    def get(self, request):
        data_list, page = PaginatorPage(request, Ad_Model.objects.order_by('-create_time').all().values('uuid', 'update_time', 'ad_name', 'ad_end_date', 'ad_remark'))
        return render(request, 'adList.html', context={'dataList': data_list, 'page': page})

    @method_decorator(login_required)
    def post(self, request):
        return create_data(request, AdForm, Ad_Model)

    @method_decorator(login_required)
    def delete(self, request):
        uuid = QueryDict(request.body).get('uuid')
        return delete_data(uuid, Ad_Model)


class SaveMode(View):
    @method_decorator(login_required)
    def get(self, request):
        obj = Save_Model.objects.first()
        if not obj: obj = Save_Model.objects.create()  # todo 建议统一初始化

        return render(request, 'save.html', {'data': dict(obj)})

    @method_decorator(login_required)
    def post(self, request):
        uuid = request.POST.get('uuid')
        return update_data(request, SaveForm, Save_Model, uuid)


class NormalAccess(View):
    @method_decorator(login_required)
    def get(self, request):
        result = [{}]
        result_list = conn.hgetall('NormalAccess')
        for k, v in result_list.items():
            value = json.loads(v.decode())
            value['ip'] = k.decode()
            b = (time.time() - value['first_time']) > NORMAL_AUTH_TIME
            if not b: result.append(value)
        dataList, page = access_auto_page(request, result)
        return render(request, 'normalList.html', context={'dataList': dataList, 'page': page})

    @method_decorator(login_required)
    def post(self, request):
        ip = request.POST.get('ip')
        try:
            try:
                d = json.loads(conn.hget('NormalAccess', ip).decode())
            except Exception as e:
                return JsonResponse({'code': 4, 'msg': f'IP读取出错:{e}'})
            d['freeze_time'] = time.time()
            result = conn.hset('FreezeAccess', ip, json.dumps(d))
            if result:
                conn.hdel('NormalAccess', ip)
                return JsonResponse({'code': 0})
            return JsonResponse({'code': 1, 'msg': '冻结失败，或已存在冻结'})
        except Exception as e:
            return JsonResponse({'code': 4, 'msg': f'冻结处理异常：{str(e)}'})

    @method_decorator(login_required)
    def delete(self, request):
        ip = QueryDict(request.body).get('uuid')
        return delete_access(conn, ip, 'NormalAccess')


class FreezeAccess(View):
    @method_decorator(login_required)
    def get(self, request):
        result = [{}]
        result_list = conn.hgetall('FreezeAccess')
        for k, v in result_list.items():
            value = json.loads(v.decode())
            value['ip'] = k.decode()
            b = ((time.time() - value['freeze_time']) / 60) >= FREEZE_TIME
            if not b: result.append(value)
        dataList, page = access_auto_page(request, result)
        return render(request, 'freezeList.html', context={'dataList': dataList, 'page': page})

    @method_decorator(login_required)
    def post(self, request):
        ip = request.POST.get('ip')
        try:
            try:
                d = json.loads(conn.hget('FreezeAccess', ip).decode())
            except Exception as e:
                return JsonResponse({'code': 4, 'msg': f'IP读取出错:{e}'})
            d['forbid_time'] = time.time()
            result = conn.hset('ForbidAccess', ip, json.dumps(d))
            if result:
                conn.hdel('FreezeAccess', ip)
                return JsonResponse({'code': 0})
            return JsonResponse({'code': 1, 'msg': '添加黑名单失败，或已存在黑名单'})
        except Exception as e:
            return JsonResponse({'code': 4, 'msg': f'处理异常：{str(e)}'})

    @method_decorator(login_required)
    def delete(self, request):
        ip = QueryDict(request.body).get('uuid')
        return delete_access(conn, ip, 'FreezeAccess')


class ForbidAccess(View):
    @method_decorator(login_required)
    def get(self, request):
        result = [{}]
        result_list = conn.hgetall('ForbidAccess')
        for k, v in result_list.items():
            value = json.loads(v.decode())
            value['ip'] = k.decode()
            result.append(value)
        dataList, page = access_auto_page(request, result)
        return render(request, 'forbidList.html', context={'dataList': dataList, 'page': page})

    @method_decorator(login_required)
    def delete(self, request):
        ip = QueryDict(request.body).get('uuid')
        return delete_access(conn, ip, 'ForbidAccess')
